import { ref, nextTick } from 'vue'
import type { Ref } from 'vue'
import type { ValidateErrorEntity } from 'ant-design-vue/es/form/interface'
import type { antFormType } from '@/types/interface/antd'
import useErrorMessage from './useErrorMessage'

/**
 * @method 使用form的hooks
 */
export default function useForm<F = any>() {
  const { alertError } = useErrorMessage()
  /**表单model */
  const formState: Ref<Partial<F>> = ref({})
  /**表单校验提示 */
  const validateMessages = { required: '${label}不能为空' }
  /**表单对象ref */
  const formRef = ref<antFormType>()

  /**
   * @method 设置表单数据
   * @param data 需要设置的数据
   * @returns  void
   */
  function setFormStateData(data: Record<string, any>) {
    Object.assign(formState.value, data)
  }

  /**
   * @method 表单校验
   * @returns  Promise<Record<string, any> | ValidateErrorEntity>
   */
  async function formValidateFields(): Promise<Partial<F> | ValidateErrorEntity> {
    return new Promise<Partial<F> | ValidateErrorEntity>(async (resolve, reject) => {
      try {
        await formRef.value?.validateFields()
        resolve(formState.value as Partial<F>)
      } catch (error: any) {
        alertError(error)
        reject(error as ValidateErrorEntity)
      }
    })
  }

  /**
   * @method 移除表单项的校验结果。传入待移除的表单项的 name 属性或者 name 组成的数组，如不传则移除整个表单的校验结果
   * @param nameList 表单对应的name字段组成的数组
   * @returns void
   */
  function clearValidate(nameList?: string | (string | number)[]) {
    if (!nameList) {
      nextTick(() => {
        formRef.value?.clearValidate()
        return
      })
    }
    if (nameList?.length) {
      if (!Array.isArray(nameList)) {
        throw new Error('移除表单校验的name必须为一个数组')
      } else {
        formRef.value?.clearValidate(nameList)
      }
    }
  }

  /**
   * @method 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
   * @param nameList 表单对应的name字段组成的数组
   * @returns void
   */
  function resetFields(nameList?: string | (string | number)[]) {
    if (!nameList) {
      formRef.value?.resetFields()
      return
    }
    if (nameList?.length) {
      if (!Array.isArray(nameList)) {
        throw new Error('重置的name必须为一个数组')
      } else {
        formRef.value?.resetFields(nameList)
      }
    }
  }

  return {
    formRef,
    formState,
    resetFields,
    clearValidate,
    validateMessages,
    setFormStateData,
    formValidateFields,
  }
}
